package com.freewater.springboot.demo.core.resolvabletype.eg3;

import org.springframework.core.ResolvableType;

// ResolvableType.isAssignableFrom方法作用:
// Determine whether this ResolvableType is assignable from the specified other type.
// Attempts to follow the same rules as the Java compiler, considering whether both the resolved Class is assignable from the given type
// as well as whether all generics are assignable.
public class Main {

    public static void main(String[] args) {
        /* 两个ParameterizedType类型的兼容性测试（注意：isAssignableFrom方法算法中会对比泛型参数类型是否兼容） */
        // ParameterizedType1与ParameterizedType2不兼容是因为第二个泛型参数类型不兼容(Integer与Number不是相同的类)
        ResolvableType type1 = ResolvableType.forClass(Converter.class, StrToIntConverter.class);
        ResolvableType type2 = ResolvableType.forClass(Converter.class, StrToNumConverter.class);
        System.out.println(type1);// com.freewater.springboot.demo.core.resolvabletype.eg3.Converter<java.lang.String, java.lang.Integer>
        System.out.println(type2);// com.freewater.springboot.demo.core.resolvabletype.eg3.Converter<java.lang.String, java.lang.Number>
        System.out.println(type1.isAssignableFrom(type2));// false
        System.out.println(type2.isAssignableFrom(type1));// false
        // 等同于
        ResolvableType type3 = ResolvableType.forType(StrToIntConverter.class.getGenericInterfaces()[0]);
        ResolvableType type4 = ResolvableType.forType(StrToNumConverter.class.getGenericInterfaces()[0]);
        System.out.println(type3);// com.freewater.springboot.demo.core.resolvabletype.eg3.Converter<java.lang.String, java.lang.Integer>
        System.out.println(type4);// com.freewater.springboot.demo.core.resolvabletype.eg3.Converter<java.lang.String, java.lang.Number>
        System.out.println(type3.isAssignableFrom(type4));// false
        System.out.println(type4.isAssignableFrom(type3));// false
        // 等同于
        ResolvableType type5 = ResolvableType.forClassWithGenerics(Converter.class, String.class, Integer.class);
        ResolvableType type6 = ResolvableType.forClassWithGenerics(Converter.class, String.class, Number.class);
        System.out.println(type5);// com.freewater.springboot.demo.core.resolvabletype.eg3.Converter<java.lang.String, java.lang.Integer>
        System.out.println(type6);// com.freewater.springboot.demo.core.resolvabletype.eg3.Converter<java.lang.String, java.lang.Number>
        System.out.println(type5.isAssignableFrom(type6));// false
        System.out.println(type6.isAssignableFrom(type5));// false

        /* 一个Class类型与另外一个ParameterizedType类型的兼容性测试（注意：isAssignableFrom方法算法中会对比泛型参数类型是否兼容） */
        ResolvableType type7 = ResolvableType.forClass(Converter.class);
        System.out.println(type7.isAssignableFrom(type1));// true
        System.out.println(type7.isAssignableFrom(type2));// true
        System.out.println(type7.isAssignableFrom(type3));// true
        System.out.println(type7.isAssignableFrom(type4));// true
        System.out.println(type7.isAssignableFrom(type5));// true
        System.out.println(type7.isAssignableFrom(type6));// true
    }
}
